package com.xiyu.service.service.order;

import com.xiyu.service.repository.customer.info.CustomerInfoRepository;
import com.xiyu.service.service.setting.BusinessFieldService;
import com.xiyu.service.vo.sales.SalesCancelInput;
import com.xiyu.service.enums.sales.SalesOrderStatusEnum;
import com.xiyu.service.service.infra.data.DictNoService;
import com.xiyu.service.vo.sales.SalesSingleGetOutput;
import com.xiyu.service.vo.sales.SalesCheckInput;
import com.xiyu.service.vo.sales.SalesUpdateInput;
import com.xiyu.service.model.sales.SalesOrderDraft;
import com.xiyu.service.vo.sales.SalesCreateInput;
import com.xiyu.service.model.sales.SalesOrder;
import com.xiyu.service.repository.sales.SalesOrderRepository;
import com.xiyu.service.vo.sales.SalesPageQueryOutput;
import com.xiyu.service.vo.sales.SalesPageQueryInput;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.babyfish.jimmer.Page;
import java.util.*;

import org.springframework.transaction.annotation.Transactional;
import com.xiyu.service.util.entity.EntityUtils;
import com.xiyu.service.framework.web.web.core.pojo.PageResult;
import com.xiyu.service.convert.order.SalesConvert;

import static com.xiyu.service.framework.exception.util.ServiceExceptionUtil.exception;
import static com.xiyu.service.errorCode.order.SalesErrorCode.*;

/**
 * 销售订单 Service 实现类
 */
@Service
@Validated
public class SalesServiceImpl implements SalesService {

    @Resource
    private SalesOrderRepository salesOrderRepository;

    @Resource
    private DictNoService dictNoService;

    @Resource
    private CustomerInfoRepository customerInfoRepository;

    @Resource
    private BusinessFieldService businessFieldService;




    @Override
    public PageResult<SalesPageQueryOutput> pageQuery(SalesPageQueryInput inputVO) {
        Page<SalesOrder> pageSalesOrder = salesOrderRepository.pageQuery(inputVO);
        List<SalesPageQueryOutput> listSalesOrder = SalesConvert.INSTANCE.pageQueryOutputConvert(pageSalesOrder.getRows());
        return new PageResult<>(listSalesOrder, pageSalesOrder.getTotalRowCount());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean create(SalesCreateInput inputVO) {
        SalesOrder newSalesOrder = SalesConvert.INSTANCE.createInputConvert(inputVO);
        newSalesOrder = SalesOrderDraft.$.produce(newSalesOrder, draft -> draft.setSalesNo(dictNoService.produceNo("salesOrder")).setStatus(SalesOrderStatusEnum.UNCHECK.getValue()));
        salesOrderRepository.insert(newSalesOrder);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(SalesUpdateInput inputVO) {
        Optional<SalesOrder> optionalOldSalesOrder = salesOrderRepository.findById(inputVO.getId());
        if(optionalOldSalesOrder.isEmpty()){
            throw exception(SALES_ORDER_NOT_EXIST);
        }
        SalesOrder updateSalesOrder = SalesConvert.INSTANCE.updateInputConvert(inputVO);
        if (!EntityUtils.isEquals(optionalOldSalesOrder.get(), updateSalesOrder))
            salesOrderRepository.update(updateSalesOrder);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean check(SalesCheckInput inputVO) {
        Long dealState = businessFieldService.getStateDealOptionId();
        for(Long id : inputVO.getIds()){
            SalesOrder salesOrder = salesOrderRepository.findNullable(id);
            if(salesOrder == null){
                throw exception(SALES_ORDER_NOT_EXIST);
            }
            if(!salesOrder.status().equals(SalesOrderStatusEnum.UNCHECK.getValue())){
                throw exception(SALES_ORDER_MUST_UNCHECK);
            }
            salesOrderRepository.updateStatus(id, SalesOrderStatusEnum.DONE.getValue());
            // 更新客户状态
            customerInfoRepository.updateState(id, dealState);
        }
        return true;
    }

    @Override
    public SalesSingleGetOutput singleGet(Long id) {
        Optional<SalesOrder> optionSalesOrder = salesOrderRepository.findDetailById(id);
        if(optionSalesOrder.isEmpty()){
            throw exception(SALES_ORDER_NOT_EXIST);
        }
        return SalesConvert.INSTANCE.singleGetOutputConvert(optionSalesOrder.get());

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean cancel(SalesCancelInput inputVO) {
        for(Long id : inputVO.getIds()){
            SalesOrder salesOrder = salesOrderRepository.findNullable(id);
            if(salesOrder == null){
                throw exception(SALES_ORDER_NOT_EXIST);
            }
            if(!salesOrder.status().equals(SalesOrderStatusEnum.UNCHECK.getValue())){
                throw exception(SALES_ORDER_MUST_UNCHECK);
            }
            salesOrderRepository.updateStatus(id, SalesOrderStatusEnum.CANCEL.getValue());
        }
        return true;
    }

}
